import { Injectable } from '@nestjs/common'
import { ConfigService } from '@nestjs/config'
import AlipaySdk from 'alipay-sdk'
import moment from 'moment'
import { nanoid } from 'nanoid'
import WxPay from 'wechatpay-node-v3'
import { User } from '../../src/models/User'
import { RedisService } from '../../src/redis/redis.service'
import { AppError } from '../../src/utils/AppError'

@Injectable()
export class PaymentService {
  private alipay: any
  private wxpay: any

  constructor(private readonly configService: ConfigService, private readonly redis: RedisService) {
    // 支付宝配置
    this.alipay = new AlipaySdk({
      appId: this.configService.get('ALIPAY_APP_ID'),
      privateKey: this.configService.get('ALIPAY_PRIVATE_KEY'),
      alipayPublicKey: this.configService.get('ALIPAY_PUBLIC_KEY'),
    })

    // 微信支付配置
    this.wxpay = new WxPay({
      appid: this.configService.get('WECHAT_APP_ID'),
      mchid: this.configService.get('WECHAT_MCH_ID'),
      privateKey: this.configService.get('WECHAT_PRIVATE_KEY'),
      serial_no: this.configService.get('WECHAT_SERIAL_NO'),
      key: this.configService.get('WECHAT_API_KEY'),
      publicKey: this.configService.get('WECHAT_PUBLIC_KEY'),
    })
  }

  // 创建支付订单
  async createOrder(userId: string, amount: number, channel: 'alipay' | 'wechat') {
    // 验证金额
    const minAmount = 1
    const maxAmount = 10000
    if (amount < minAmount || amount > maxAmount) {
      throw new AppError(400, '充值金额必须在1元到10000元之间', 'VALIDATION_ERROR')
    }

    // 生成订单号
    const orderId = `PAY${moment().format('YYYYMMDDHHmmss')}${nanoid(8)}`

    // 保存订单信息
    await this.redis.set(
      `order:${orderId}`,
      JSON.stringify({
        userId,
        amount,
        channel,
        status: 'pending',
        createTime: Date.now(),
        expireTime: Date.now() + 30 * 60 * 1000, // 30分钟过期
      })
    )

    // 创建支付参数
    if (channel === 'alipay') {
      return this.createAlipayOrder(orderId, amount)
    } else {
      return this.createWechatOrder(orderId, amount)
    }
  }

  // 创建支付宝订单
  private async createAlipayOrder(orderId: string, amount: number) {
    const params = {
      subject: '虚拟币充值',
      outTradeNo: orderId,
      totalAmount: amount.toFixed(2),
      notifyUrl: this.configService.get('ALIPAY_NOTIFY_URL'),
    }

    return this.alipay.pageExec('alipay.trade.page.pay', {
      ...params,
      productCode: 'FAST_INSTANT_TRADE_PAY',
    })
  }

  // 创建微信支付订单
  private async createWechatOrder(orderId: string, amount: number) {
    const params = {
      description: '虚拟币充值',
      out_trade_no: orderId,
      amount: {
        total: Math.floor(amount * 100),
      },
      notify_url: this.configService.get('WECHAT_NOTIFY_URL'),
    }

    return this.wxpay.transactions_native(params)
  }

  // 处理支付回调
  async handleCallback(channel: string, data: any) {
    let orderId, amount, status

    if (channel === 'alipay') {
      const result = await this.alipay.checkNotifySign(data)
      if (!result) throw new AppError(400, '支付宝回调签名验证失败', 'PAYMENT_ERROR')

      orderId = data.out_trade_no
      amount = parseFloat(data.total_amount)
      status = data.trade_status === 'TRADE_SUCCESS' ? 'success' : 'failed'
    } else if (channel === 'wechat') {
      const result = await this.wxpay.verifySign(data)
      if (!result) throw new AppError(400, '微信支付回调签名验证失败', 'PAYMENT_ERROR')

      orderId = data.out_trade_no
      amount = data.amount.total / 100
      status = data.trade_state === 'SUCCESS' ? 'success' : 'failed'
    }

    // 更新订单状态
    const orderData = JSON.parse(await this.redis.get(`order:${orderId}`))
    orderData.status = status
    await this.redis.set(`order:${orderId}`, JSON.stringify(orderData))

    if (status === 'success') {
      // 充值成功，增加用户虚拟币
      const coins = Math.floor(amount * 10) // 1元=10虚拟币
      const orderInfo = JSON.parse(await this.redis.get(`order:${orderId}`))
      await User.findByIdAndUpdate(orderInfo.userId, { $inc: { coins } })
    }

    return { success: true }
  }
}
